
#include "Settings.h"
#include "ReadSet.h"


void toupper(string &data) {
	for(size_t i = 0; i < data.size(); i++) {
		data[i] = toupper(data[i]);
	}
}

ReadSet::ReadSet(string fileName, const int readLength) :
	_readLength(readLength) {
	_ifs.open(fileName.c_str());
}

ReadSet::~ReadSet() {
	_ifs.close();
}

bool ReadSet::isGoodRead(string read) {
	if(read.size() != _readLength) {
		cout << "Error: The read has a different read length;" << endl;
		exit(-1);
		return false;
	}

	char c;
	for(size_t i = 0; i < read.size(); i++) {
		//c = toupper(read[i]);	
		c = read[i];
		if(c != 'A' && c != 'T' && c != 'C' && c != 'G') {
			cout << "Error: the read has an unknown base: " << c << endl;
			exit(-1);
			return false;
		}
	}
	return true;
}

int ReadSet::fetch(char* base, char* qscore, const int numReadFetch) {
	int numFetched = 0;
	string line;

	for(int i = 0; i < numReadFetch; i++) {
		//title
		if(!getline(_ifs, line)) {break;}
		//base
		if(!getline(_ifs, line)) {break;} 
		else {
			//convert to upper case
			toupper(line);
			if(!isGoodRead(line)) {
				continue;
			} else {
				line.copy(base + numFetched*_readLength, _readLength);
			}
		} 
		//title
		if(!getline(_ifs, line)) {break;};
		//qual scores
		if(!getline(_ifs, line)) {break;}
		else {
			line.copy(qscore + numFetched*_readLength, _readLength);
		}
		++numFetched;
	}

	return numFetched;
}

void ReadSet::encode(QuerySet &querySet, const char* read, 
                        const int numRead, const int readLength, bool isTwoStrand) {
	const int numWordPerQuery = numEncodedWord(readLength);
	if(!isTwoStrand) {
		querySet.alloc(numRead, numWordPerQuery, readLength, false);
	} else {
		querySet.alloc(numRead*2, numWordPerQuery, readLength, true);
	}


	//the positive strand
	memset(querySet.query, 0, sizeof(unsigned int)*numWordPerQuery*numRead);
	for(int readId = 0; readId < numRead; readId++) {
		encodeSingle(querySet.query + readId*numWordPerQuery, 
				read + readId*readLength, readLength);
	}	

	//the negative strand, if any
	if(isTwoStrand) {
		memset(querySet.query + numWordPerQuery*numRead, 0, sizeof(unsigned int)*numWordPerQuery*numRead);
		char* revRead = new char[readLength];
		for(int readId = 0; readId < numRead; readId++) {
			reverse_complement(revRead, read + readId*readLength, readLength);
			encodeSingle(querySet.query + numRead*numWordPerQuery + readId*numWordPerQuery,
					revRead, readLength);
		}

		delete[] revRead;
	}
}

